package ua.yandex.collections;

/**
 *
 * @author Кирилл
 */

public class MyArrayList implements MyList{
    private Object[] arrayList;
    private int size;
    
    private static final int DEFAULT_CAPACITY = 10;
   
    public MyArrayList(){
        arrayList = new Object[DEFAULT_CAPACITY];
        size = 0;
    }
    public MyArrayList(int initialCapacity){
        arrayList = new Object[initialCapacity];
        size = 0;
    }
            
    public void ensureCapacity(int newCapacity){
        assert(size <= arrayList.length);
        
        Object[] tempList = new Object[arrayList.length];
        System.arraycopy(arrayList, 0, tempList, 0, size);
        arrayList = new Object[newCapacity];
        System.arraycopy(tempList, 0, arrayList, 0, size);
    }
    
    private boolean checkBoarder(int index){
        if (index < 0){
            return false;
        }
        return (index <= size);
    }
    
    @Override
    public void add(Object e) {
        if (size >= arrayList.length){
            ensureCapacity(arrayList.length << 1);
        }
        arrayList[size++] = e;
    }

    @Override
    public void add(int index, Object e) {
        // index must belong to [0,size]. "index = size" - means you push element into tail of the array
        if (!checkBoarder(index)){
            throw new IllegalListIndexException("index does not belong to [0,size]");
        }
        if (size >= arrayList.length){
            ensureCapacity(arrayList.length << 1);
        }
        for (int i = size; i > index; i --){
            arrayList[i] = arrayList[i - 1];
        }
        arrayList[index] = e;
        size ++;
    }

    @Override
    public void addAll(Object[] c) {
        for (Object e : c){
            if (size >= arrayList.length){
                ensureCapacity(arrayList.length << 1);
            }
            add(e);
        }
    }

    @Override
    public void addAll(int index, Object[] c) {
        if (!checkBoarder(index)){
            throw new IllegalListIndexException("index does not belong to [0,size]");
        }
        for (Object e : c){
            add(index++ , e);
        }
    }

    @Override
    public Object get(int index) {
        if (index == size || !checkBoarder(index)){
            throw new IllegalListIndexException("index does not belong to [0,size-1]");
        }
        return arrayList[index];
    }

    @Override
    public Object remove(int index) {
        if (index == size || !checkBoarder(index)){
            throw new IllegalListIndexException("index does not belong to [0,size-1]");
        }
        Object result = get(index);
        for (int i = index; i < size; i ++){
            arrayList[i] = arrayList[i + 1];
        }
        size --;
        if ((size << 1) <= arrayList.length && arrayList.length > DEFAULT_CAPACITY){
            ensureCapacity(Math.min(DEFAULT_CAPACITY, arrayList.length >> 1));
        }
        return result;
    }

    @Override
    public void set(int index, Object e) {
        if (index == size || !checkBoarder(index)){
            throw new IllegalListIndexException("index does not belong to [0,size-1]");
        }
        arrayList[index] = e;
    }

    @Override
    public int indexOf(Object o) {
        for (int i = 0 ;i < size; i ++){
            if (arrayList[i] == o){
                return i;
            }
        }
        return -1;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void clear() {
        arrayList = new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    @Override
    public boolean isEmpty() {
        return (size == 0);
    }

    @Override
    public Object[] toArray() {
        Object[] tempList = new Object[size];
        System.arraycopy(arrayList, 0, tempList, 0, size);
        return tempList;
    }
    
    @Override
    public String toString(){
        String string = new String();
        if (size > 0) {
            string += '[';
            for (int i = 0 ; i < size - 1 ; i++) {
                string += (arrayList[i].toString());
                string += (",");
                string += " ";
            }
            string += (arrayList[size - 1].toString());
            string += ("]");
        }
        System.out.println(string);
        return string.toString();
    }
    
}
